package aidlserver.app

import android.app.Notification
import android.app.Service
import android.content.Intent
import android.os.*
import android.widget.Toast
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationManagerCompat
import com.example.commonlib.CLogUtil
import kotlinx.coroutines.*
import java.io.ByteArrayOutputStream
import java.nio.charset.StandardCharsets

class BookService : Service() {

    private var handler = Handler(Looper.getMainLooper())
    private lateinit var scope: CoroutineScope
    private var job: Job? = null

    override fun onCreate() {
        super.onCreate()
        CLogUtil.d("scope inited")
        scope = CoroutineScope(Dispatchers.IO)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannelCompat.Builder(
                "bookService", NotificationManagerCompat.IMPORTANCE_DEFAULT
            ).setName("bookServiceChannel").build()
            val notification = Notification.Builder(this, channel.id).setSmallIcon(R.mipmap.ic_launcher).setWhen(System.currentTimeMillis())
                .setContentTitle("Aidl Book Service Demo").build()
            NotificationManagerCompat.from(this).createNotificationChannel(channel)
            startForeground(1, notification)
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        println("xxxx onStartCommand")
        return super.onStartCommand(intent, flags, startId)
    }

    private var myBinder = object : IBook.Stub() {
        override fun borrowBook(number: String?, count: Int) {
            println("xxxx borrow number = $number count = $count")
            handler.post {
                Toast.makeText(
                    this@BookService, "borrowBook $number $count", Toast.LENGTH_SHORT
                ).show()
            }
        }

        override fun sendfile(bundle: Bundle?, callback: IAidlCallback?) {
            CLogUtil.d("received sendfile")
            job?.cancel()
            job = scope.launch {
                val fileDescriptor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                    bundle?.getParcelable("fileFd", ParcelFileDescriptor::class.java) ?: return@launch
                } else {
                    bundle?.getParcelable("fileFd") ?: return@launch
                }
                val cis = ParcelFileDescriptor.AutoCloseInputStream(fileDescriptor)
                val buffer = ByteArray(1024)
                val bos = ByteArrayOutputStream()
                while (true) {
                    val len = cis.read(buffer)
                    if (len != -1) {
                        bos.write(buffer, 0, len)
                    } else {
                        break
                    }
                }
                cis.close()
                val readStr = bos.toString()
                CLogUtil.d("read str is $readStr")
                withContext(Dispatchers.Main) {
                    UiHelper.invokeCallback(readStr)
                }
                callback?.onExecComplete()
            }
        }
    }

    override fun onBind(p0: Intent?): IBinder {
        return myBinder
    }

    override fun onUnbind(intent: Intent?): Boolean {
        scope.cancel()
        return super.onUnbind(intent)
    }

    override fun onDestroy() {
        super.onDestroy()
        CLogUtil.d("onDestroy")
        scope.cancel()
    }
}